/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package graph.plotter;

import edu.uci.ics.jung.algorithms.layout.CircleLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.algorithms.scoring.DegreeScorer;
import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer.VertexLabel.Position;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.util.List;
import javax.swing.JFrame;
import org.apache.commons.collections15.Transformer;

public class Jung {

    public Graph<String, String> graph = null;
    VisualizationViewer<String, String> vv = null;
    String diameterNode1 = "dummyid";
    String diameterNode2 = "dummyid";
    String minDegreeNode = "dummyid";
    String maxDegreeNode = "dummyid";
    boolean isDegreeChecking = false;
    boolean isDiameterChecking = false;

    public Jung() {
        graph = new SparseMultigraph<String, String>();
    }

    public void showGraph(Graph<String, String> g) {
        Layout<String, String> layout = new CircleLayout<String, String>(g);
        layout.setSize(new Dimension(400, 400));
        vv = new VisualizationViewer<String, String>(layout);
        Transformer<String, Paint> vertexPaint = new Transformer<String, Paint>() {
//            private final Color[] palette = {Color.GREEN, Color.BLUE, Color.RED};

            public Paint transform(String s) {
                if (isDegreeChecking == true) {
                    if (s.equals(minDegreeNode)) {
                        return Color.PINK;
                    }
                    if (s.equals(maxDegreeNode)) {
                        return Color.RED;
                    }
                }
                if (isDiameterChecking == true) {
                    if (s.equals(diameterNode1) || s.equals(diameterNode2)) {
                        return Color.BLUE;
                    }
                }
                return Color.YELLOW;//                        palette[Integer.valueOf(s) % palette.length];
            }
        };
        vv.setPreferredSize(new Dimension(550, 550)); //Sets the viewing area size
        vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
        vv.getRenderContext().setVertexFillPaintTransformer(vertexPaint);
        vv.getRenderer().getVertexLabelRenderer().setPosition(Position.CNTR);
        DefaultModalGraphMouse gm = new DefaultModalGraphMouse();
        gm.setMode(ModalGraphMouse.Mode.PICKING);

        vv.setGraphMouse(gm);
        JFrame frame = new JFrame("GrowthNet");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(vv);
        frame.pack();
        frame.setVisible(true);
    }

    public void addVertexToGraph(String vertex) {

//        System.out.println("Adding vertex: " + vertex);
        graph.addVertex(vertex);
        if (vv != null) {
            vv.repaint();
        }
    }

    public void removeEdgeFromGraph(String vertex1, String vertex2) {
        if (graph.containsVertex(vertex1) && graph.containsVertex(vertex2)) {
            if (graph.isNeighbor(vertex1, vertex2) == true) {
//                System.out.println("Removing Edge Between: " + vertex1 + "-" + vertex2);
                graph.removeEdge("E:" + vertex1 + "-" + vertex2);
                graph.removeEdge("E:" + vertex2 + "-" + vertex1);
            }
        }
        vv.repaint();
    }

    public void removeVertexFromGraph(String vertex) {
        if (graph.containsVertex(vertex)) {
//            System.out.println("Degree: " + getVertexDegree(vertex));
            graph.removeVertex(vertex);
        } else {
            System.out.println("Vertex not found: " + vertex);
        }
        vv.repaint();
    }

    public void addEdgeToGraph(String vertex1, String vertex2) {
        if ((graph.isNeighbor(vertex1, vertex2) == false) && (vertex1.equals(vertex2) == false)) {
            graph.addEdge("E:" + vertex1 + "-" + vertex2, vertex1, vertex2);
        }
        if (vv != null) {
            vv.repaint();
        }
    }

    public int getVertexDegree(String vertex) {
        DegreeScorer degreeScorer = new DegreeScorer(graph);
        return degreeScorer.getVertexScore(vertex);
    }

    public int getDiameter(String vertex1, String vertex2) {
        DijkstraShortestPath<String, String> alg = new DijkstraShortestPath(graph);
        List<String> l = alg.getPath(vertex1, vertex2);
        isDiameterChecking = false;
        isDegreeChecking = false;  
//        System.out.println(l);
        return l.size();
    }

    public void highlightMinMaxDegreeNodes(String vertex1, String vertex2) {
        isDegreeChecking = true;
        isDiameterChecking = false;
        minDegreeNode = vertex1;
        maxDegreeNode = vertex2;
        vv.repaint();
    }

    public void highlightDiameterNodes(String dv1, String dv2) {
        isDiameterChecking = true;
        isDegreeChecking = false;
        diameterNode1 = dv1;
        diameterNode2 = dv2;
        System.out.println(dv1 + " , " + dv2);
        vv.repaint();
    }
}
